package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.attendance.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadLocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentDTOMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentDTOService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysDepartmentDTOServiceImpl implements SysDepartmentDTOService {
    @Autowired
    private SysDepartmentDTOMapper departmentDTOMapper;

    //获取组织架构列表
    @Override
    public List<SysDepartmentDTO> queryDepartmentList() {
        List<SysDepartmentDTO> departmentDTOList = queryChildrenDepartmentList(0L);


        return departmentDTOList;
    }

    /**
     * 查看当前企业id下的所有顶级部门
     */

    @Override
    public List<Long> queryDepartmentIds() {
        //运用LambdaQueryWrapper查找对应的
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());//企业id
        wrapper.eq(SysDepartment::getParentId, 0);//顶级部门
        List<SysDepartment> departments = departmentDTOMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(departments)) {
            List<Long> idList = departments.stream().map(department -> {
                return department.getId();
            }).collect(Collectors.toList());
            return idList;
        }
        return new ArrayList<>();
    }


    /**
     * 获取简单的列表
     */
    @Autowired
    private SysCompanyUserMapper companyUserMapper;

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long departmentId, Integer includeMember) {
        ArrayList<DepartmentOrUserSimpleDTO> all = new ArrayList<>();

        //先查子部门
        LambdaQueryWrapper<SysDepartment> departmentQW = new LambdaQueryWrapper<>();
        departmentQW.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());//企业id
        departmentQW.eq(SysDepartment::getParentId, departmentId);
        List<SysDepartment> departmentList = departmentDTOMapper.selectList(departmentQW);

        //把子级部门转换为,返回值类型列表
        List<DepartmentOrUserSimpleDTO> departmentSimpleList = departmentList.stream().map(department -> {
            DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
            departmentOrUserSimpleDTO.setName(department.getName());
            departmentOrUserSimpleDTO.setId(department.getId());
            departmentOrUserSimpleDTO.setType(1);
            return departmentOrUserSimpleDTO;
        }).collect(Collectors.toList());

        all.addAll(departmentSimpleList);

        //健壮性判断includeMember是否为0,为0就是包含员工信息
        if (includeMember == 0) {
            LambdaQueryWrapper<SysCompanyUser> companyUserQW = new LambdaQueryWrapper<>();
            companyUserQW.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            companyUserQW.eq(SysCompanyUser::getDepartmentId, departmentId);
            List<SysCompanyUser> sysCompanyUsers = companyUserMapper.selectList(companyUserQW);

            //转换格式
            List<DepartmentOrUserSimpleDTO> userSimpleList = sysCompanyUsers.stream().map(sysCompanyUser -> {
                DepartmentOrUserSimpleDTO userSimpleDTO = new DepartmentOrUserSimpleDTO();
                userSimpleDTO.setType(2);//员工
                userSimpleDTO.setName(sysCompanyUser.getUserName());
                userSimpleDTO.setId(sysCompanyUser.getId());
                return userSimpleDTO;
            }).collect(Collectors.toList());

            all.addAll(userSimpleList);
        }

        return all;
    }

    /**
     *根据用户id获所在的部门和上级,上上级部门
     * */

    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {
        ArrayList<Long> list = new ArrayList<>();
        //根据员工id获取员工信息
        SysCompanyUser companyUser = companyUserMapper.selectById(companyUserId);
        //从员工信息中获取该员工所属的部门
        Long departmentId = companyUser.getDepartmentId();
        //健壮性判断
        if (departmentId==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据部门id查看是否是顶级部门

        while (true){
            SysDepartment department = departmentDTOMapper.selectById(departmentId);
            Long parentId = department.getParentId();

            if (parentId==0){
                break;
            }
            list.add(parentId);
            departmentId=parentId;
        }


        return list;
    }

    /*
     *运用递归方法进行查询
     * */
    public List<SysDepartmentDTO> queryChildrenDepartmentList(Long parentId) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(SysDepartment::getCompanyId, companyId);
        wrapper.eq(SysDepartment::getParentId, parentId);
        List<SysDepartment> sysDepartmentList = departmentDTOMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(sysDepartmentList)) {
            List<SysDepartmentDTO> departmentDTOList = BeanHelper.copyWithCollection(sysDepartmentList, SysDepartmentDTO.class);
            //遍历 查询每一个子部门 的子部门
            for (SysDepartmentDTO sysDepartmentDTO : departmentDTOList) {
                List<SysDepartmentDTO> dtoList = this.queryChildrenDepartmentList(sysDepartmentDTO.getId());
                sysDepartmentDTO.setChildren(dtoList);
            }
            return departmentDTOList;
        }
        return new ArrayList<>();
    }
}
